#include "rrqHandler.h"
#include "../logger/logger.h"
#include <string.h> /*for strcpy,strlen*/
#include <errno.h> /*errno*/
#include <stdlib.h> /* for malloc */
#include <arpa/inet.h> /* for ntohs,htons */

//mark read error
enum readError{readError=0};

/**
 * author: Haim Tsolker.
 * 
 * handleRRQ
 * 
 * request - requestStruct which contain all of the required information
 *           for executing a request step
 * data - message - a request step to be sent to the client
 * 
 * file is opened for reading at position data->pos and wrap 512 characters of data.
 * if eof was reached, then < 512 characters will be wrapped.
 * the amount of character that were wrapped is saved in data->size. 
 * in case of error, data is turned into a proper error message.
 */
msg_p handleRRQ(request_p request, msg_p data)
{
	FILE* reader;
	request_p internalRequest = (request_p) request;
	memset((void*)(data->data),0,sizeof(char)*BLOCKSIZE);
	data->msgID = ntohs(0x0003);
	data->msgNumber = htons(ntohs(data->msgNumber)+1);
	if(NULL==(reader = fopen(internalRequest->fileName,"r")))
	{
		//problem openning the file
		data->msgID = ntohs(errRequest);
		data->msgNumber = ntohs(fileNotFound);
		strerror_r(errno,data->data,sizeof(char)*BLOCKSIZE);
		data->size=strlen(data->data);
		perror("fopen");
		return data;
	}
	if(!fsetpos(reader,&(data->pos)))
		;
	if(!fseek(reader,-data->offset,SEEK_CUR))
		;
	if(0==(data->size=fread((void*)(data->data), sizeof(char), BLOCKSIZE, reader)))
	{
		//reading size is bigger then 0
		if(0!=feof(reader))
		{
			//the eof indicator for <reader> is set
			char* locationOfEOF = strchr(data->data,EOF);
			if (0!=locationOfEOF)
			{
				data->size = locationOfEOF - (data->data) + 1;
			}
			else
			{
				//we get here in occassions like: the requested file was empty
				data->size = 0;
			}
		}
		else if(0!=ferror(reader))
		{
			logMessage("rrqHandler: error while reading from: %s",internalRequest->fileName);
			data->msgID = ntohs(errRequest);
			data->msgNumber = ntohs(fileNotFound);
			data->size = readError;
		}
	}
	if(!fgetpos(reader,&(data->pos)))
		;
	fclose(reader);
	return data;
}
